<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class ServiceBindingsCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:serviceBindings {name}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Add business service bindings to service provider.';

    /**
     * The placeholder for repository bindings
     *
     * @var string
     */
    public $bindPlaceholder = '//:end-bindings:';


    /**
     * The type of class being generated.
     *
     * @var string
     */
    protected $type = 'service Bindings';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $providerName = "BusinessServiceProvider";
        $path         = app()->path() . "/Providers/{$providerName}.php";

        if (!file_exists($path)) {
            // 创建provider
            $this->call('make:serviceProvider', [
                'name' => $providerName,
            ]);

            // placeholder to mark the place in file where to prepend repository bindings
            $provider = File::get($path);
            File::put($path, vsprintf(str_replace('//', '%s', $provider), [
                '//', $this->bindPlaceholder
            ]));

            // 注册serviceProvider
            $this->registerBusinessTierProvider($providerName);
        }

        // 绑定
        $provider         = File::get($path);
        $serviceInterface = '\\' . $this->getService() . "::class";
        $serviceEloquent  = '\\' . $this->getServiceImpl() . "::class";
        File::put($path, str_replace($this->bindPlaceholder, "\$this->app->singleton({$serviceInterface}, $serviceEloquent);" . PHP_EOL . '        ' . $this->bindPlaceholder, $provider));
        $this->info($this->type . ' created successfully.');
    }

    private function getService()
    {
        return "App\\Services\\" . $this->argument("name");
    }

    private function getServiceImpl()
    {
        return "App\\Services\\Impl\\" . $this->argument("name") . "Impl";
    }

    /**
     * 注册serviceProvider
     * @param string $providerName
     */
    private function registerBusinessTierProvider(string $providerName)
    {
        $path     = app()->path() . "\\Providers\\AppServiceProvider.php";
        $provider = File::get($path);;
        File::put($path, str_replace("//register", "\$this->app->register({$providerName}::class);" . PHP_EOL . '        ' . "//register", $provider));
    }
}
